package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.gameUtil.GameLogic;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.NextBetPlayerReasonEnum;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_IsAllowSideShowAck_50010;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.service.TimerService;
import com.jule.teenpatti.game.utils.log.TableLogUtil;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 被比牌用户，是否同意比牌申请
 */
@Slf4j
public class JoloGame_IsAllowSideShowReq_50010 extends ClientReq {
    private long time;

    public JoloGame_IsAllowSideShowReq_50010(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_IsAllowSideShowReq req;


    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_IsAllowSideShowReq.parseFrom(blob);
        AbstractTable table = TableService.getInstance().getTable(header.gameId + "", req.getRoomId(), req.getTableId());
        if (null != table) {
            this.setTable(table);
        } else {
            log.error("桌子不存在,roomId->" + req.getRoomId() + ", tableId->" + req.getTableId());
        }
    }

    @Override
    public void processImpl() throws Exception {
        log.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "msg ->" + req.toString());
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        String gameOrderId = req.getGameOrderId();
        int isAllow = req.getIsAllow();
        String targetUserId = req.getTargetUserId();

        AbstractTable table = getTable();

        JoloGame.JoloGame_IsAllowSideShowAck.Builder ack = JoloGame.JoloGame_IsAllowSideShowAck.newBuilder();
        ack.setUserId(userId);
        ack.setRoomId(roomId);
        ack.setTableId(tableId);
        ack.setGameOrderId(gameOrderId);
        ack.setIsAllow(isAllow);
        ack.setTargetUserId(targetUserId);
        try {
            //判断GameOrderId是否一致
            if (!gameOrderId.equals(table.getCurrGameOrderId())) {
                ack.setResult(-1);
                ack.setResultMsg("GameOrderId不匹配, currGameOrderId->" + table.getCurrGameOrderId() + ", gameOrderId->" + gameOrderId);
                ctx.writeAndFlush(new JoloGame_IsAllowSideShowAck_50010(ack.build(), header));
                return;
            }

            //判断是否需要提示客户端展示下一个行动玩家的倒计时信息
            PlayerInfo doSideShowPlayer = table.getPlayer(table.getCurrDoSideShowPlayerId());
            PlayerInfo targetSideShowPlayer = table.getPlayer(userId);
            if (null == doSideShowPlayer || null == targetSideShowPlayer) {
                ack.setResult(-1); //玩家信息不存在
                ack.setResultMsg("找不到玩家信息。playerIsNull->" + (null == doSideShowPlayer) + ", targetPlayerIsNull->" + (null == targetSideShowPlayer));
                ctx.writeAndFlush(new JoloGame_IsAllowSideShowAck_50010(ack.build(), header));
                return;
            }

            ctx.writeAndFlush(new JoloGame_IsAllowSideShowAck_50010(ack
                    .setResult(1)
                    .setIsAllow(isAllow)
                    .build(), header));

            //停止用户倒计时
            TimerService.getInstance().delTimerTask(table.getRoomTableRelation());

            PlayerInfo nextActionPlayer = null;
            if (isAllow == 0) {
                nextActionPlayer = table.getNextBetPlayer(doSideShowPlayer.getSeatNum(), NextBetPlayerReasonEnum.SIDE_SHOW_ALLOW);
                //此处可能要设置玩家为行动状态 todo
                if (nextActionPlayer != null) {
                    //设置下一个行动玩家的状态
                    nextActionPlayer.setState(PlayerStateEnum.beting);
                    // 如果本局游戏只剩两人则可以show
                    if (table.getInGamePlayers().size() == 2 && table.getSeeCardNum() == 2) {
                        nextActionPlayer.setIsCanShow(1);
                    }
                }
            }

            //清空记录的比牌双方信息
            table.setCurrDoSideShowPlayerId("");
            table.setCurrTargetSideShowPlayerId("");
            //用户不同意比牌，进入下一个行动用户的下注倒计时
            if (isAllow == 0) {
                NoticeBroadcastMessages.sideShowCompleteAllow(table, doSideShowPlayer, targetSideShowPlayer, isAllow, nextActionPlayer);
                GameLogic.betTimer(table);
            } else {
                List<String> list = new ArrayList<>();
                list.add(doSideShowPlayer.getPlayerId());
                list.add(targetSideShowPlayer.getPlayerId());
                //通知所有人有人sideshow
                NoticeBroadcastMessages.bothSideshows(table, list);
                //用户同意比牌，开启比牌倒计时(倒计时结束后，自动推送比牌结果给全部客户端)
                //广播事件：通知全部客户端，用户已经完成了是否同意比牌的操作
//                doSideShowPlayer.getHandCardTypeModel(table);
//                targetSideShowPlayer.getHandCardTypeModel(table);
//                log.debug(doSideShowPlayer.playerToString()+"发起比牌的玩家-----------------------："+doSideShowPlayer.getHandCards()[0]+":"+doSideShowPlayer.getHandCards()[1]+":"+doSideShowPlayer.getHandCards()[2]);
//                log.debug(targetSideShowPlayer.playerToString()+"被比牌的玩家-----------------------："+targetSideShowPlayer.getHandCards()[0]+":"+targetSideShowPlayer.getHandCards()[1]+":"+targetSideShowPlayer.getHandCards()[2]);
//                NoticeBroadcastMessages.sideShowBothSides(table, doSideShowPlayer, targetSideShowPlayer);
                NoticeBroadcastMessages.sideShowCompleteAllow(table, doSideShowPlayer, targetSideShowPlayer, isAllow, nextActionPlayer);
            }
            table.setLastActionTime(System.currentTimeMillis());
            TableLogUtil.allowSideShowResult(functionId, "allowSideShowResult", doSideShowPlayer.getPlayerId(), doSideShowPlayer.getNickName(),
                    table.getPlayType() + "", table.getRoomId(), table.getTableId(), table.getCurrGameOrderId(), userId, targetSideShowPlayer.getNickName());
            long timeMillis = System.currentTimeMillis() - time;
            if (timeMillis > GameConst.COST_TIME) {
                LoggerUtils.performance.info("IsAllowSideShowReq_50010,cost time:{},req:{}", timeMillis, req.toString());
            }
        } catch (Exception ex) {
            log.error("系统异常：userId->"+userId+", gameOrderId->"+gameOrderId+", message->"+ex.getMessage());
            ack.setResult(-1);
            ack.setResultMsg(ex.getMessage());
            ctx.writeAndFlush(new JoloGame_IsAllowSideShowAck_50010(ack.build(), header));
        } finally {
//            log.debug("IsAllowSideShow ACK info: "+ack.toString());
//            log.debug("IsAllowSideShow ACK bytes length: "+ack.build().toByteArray().length);
//            if(null != table){
//                log.debug("All Player info: "+System.getProperty("line.separator") + table.toStringAllPlayers());
//
//                log.debug("InGame Player info: "+System.getProperty("line.separator") + table.toStringInGamePlayers());
//            }
//            log.debug("IsAllowSideShow over. Table state: "+table.getTableStateEnum());

            long useTimes = System.currentTimeMillis() - time;
            if(useTimes > 500) {
                log.error("IsAllowSideShow。 耗时->{} 毫秒, reqNum->{}", useTimes, header.reqNum); //TODO:临时增加
            }
        }
    }
}
